package com.example.demo.leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 按照国际象棋的规则，皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
 * <p>
 * n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上，并且使皇后彼此之间不能相互攻击。
 * <p>
 * 给你一个整数 n ，返回所有不同的 n 皇后问题 的解决方案。
 * <p>
 * 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案，该方案中 'Q' 和 '.' 分别代表了皇后和空位。
 */
public class Leetcode51 {


    public static List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<>();
        // 以4皇后为例  4*4的棋盘，有2种解法
        // 记录列冲突
        boolean[] ca = new boolean[n];
        // 左斜线冲突 true代表有冲突
        // n=4 7条斜边，n=8 15条斜边
        boolean[] cb = new boolean[2 * n - 1];
        // 右斜线
        boolean[] cc = new boolean[2 * n - 1];
        // 没放 '.' 放了 'Q'
        char[][] table = new char[n][n];
        // 初始化棋盘 全为空
        for (char[] t : table) {
            Arrays.fill(t, '.');
        }
        dfs(0, n, table, ca, cb, cc, res);
        //        for (char[] t : table) {
        //            //            res.add(new String(t)
        //            List<String> arrayList = new ArrayList<>();
        //            arrayList.add(new String(t));
        //            res.add(arrayList);
        //        }
        return res;
    }

    /**
     * @param i     当前处理到第几行了
     * @param n     棋盘 4*4 n=4
     * @param table 棋盘数组
     * @param ca    列冲突
     * @param cb    左斜线冲突
     * @param cc    右斜线冲突
     */
    static void dfs(int i, int n, char[][] table, boolean[] ca, boolean[] cb, boolean[] cc, List<List<String>> res) {
        if (i == n) {
            List<String> arrayList = new ArrayList<>();
            for (char[] t : table) {
                arrayList.add(new String(t));

            }
            res.add(arrayList);
            return;
        }

        for (int j = 0; j < n; j++) {
            if (ca[j] || cb[i + j] || cc[n - 1 - (i - j)]) {
                continue;
            }
            table[i][j] = 'Q';
            // 列冲突
            ca[j] = true;
            // 左斜线
            cb[i + j] = true;
            cc[n - 1 - (i - j)] = true;
            dfs(i + 1, n, table, ca, cb, cc, res);
            // 回溯
            table[i][j] = '.';
            // 列冲突
            ca[j] = false;
            // 左斜线
            cb[i + j] = false;
            cc[n - 1 - (i - j)] = false;
        }
    }

    public static void main(String[] args) {
        System.out.println(solveNQueens(4));
    }
}
